use std
use http
use escfmt
use "dispatch"

const httpd = {params
    var srv
	
	var ip, port
	ip=params[0]
	port=params[1]
	var serveropt = ["tcp","!",ip,"!",port]
	
	std.put("httpd running {}:{}\n",ip,port)
    
    match http.announce(std.strjoin(serveropt[:], ""))
    | `std.Ok s:    srv = s
    | `std.Err e:   std.fatal("unable to announce: {}\n", e)
    ;;

    http.serve(srv, handler)
}

const handler = {srv, sess, req
    var s = std.fmt("{}", escfmt.url(req.url.path))
    var url=req.url.path
    var charform
    var signc
    const signs = [0x23,0x24]
    for sign : signs[:]
		signc=std.fmt("{x}",sign)
		charform=std.fmt("{}", (sign : char))
		//std.put("{} , {} > {}\n",req.url.path,std.strcat("%",signc),charform)
		url=std.strreplace(url,std.strcat("%",signc),charform)
    ;;
    std.put("Reading reqpath {}\n", url)
    match url
    | "/ping":  respond(srv, sess, 200, "pong")
    | fspath:   showfile(srv, sess, url)
    ;;
}

const showfile = {srv, sess, path
    var eb : byte[128]
    var p

    p = std.pathcat(".", path)
    match std.slurp(p)
    | `std.Ok buf:
        respond(srv, sess, 200, buf)
        std.slfree(buf)
    | `std.Err e:
        respond(srv, sess, 404, std.bfmt(eb[:], "error reading {}: {}\n", p, e))
    ;;
    std.slfree(p)
}


const respond = {srv, sess, status, body
    var resp

    resp = std.mk([
        .status=status,
        .hdrs = [][:],
        .len = 0,
        .err = `std.None,
        .reason = "",
        .body = body,
        .enc = `http.Length
    ])
    http.respond(srv, sess, resp)
    std.free(resp)
}

const __init__ = {
	dispatch.register("httpd", httpd)
}
